package com.vichat.user.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.vichat.common.cache.RedisHelper;
import com.vichat.common.constant.GlobalConstant;
import com.vichat.common.constant.I18nConstant;
import com.vichat.common.enums.RecordType;
import com.vichat.common.exception.ViChatException;
import com.vichat.common.signal.CmdUtil;
import com.vichat.common.util.*;
import com.vichat.common.vo.PageFilter;
import com.vichat.core.dao.BaseDaoI;
import com.vichat.user.entity.*;
import com.vichat.user.service.IUserService;
import com.vichat.user.vo.*;
import net.dongliu.apk.parser.utils.Strings;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.type.StringType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.net.URLDecoder;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * Created by ranjx on 2017/10/13.
 */

@Service("userService")
public class UserServiceImpl implements IUserService {
    protected static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
    ExecutorService tp = Executors.newCachedThreadPool();

    @Autowired
    private BaseDaoI<UserParty> partyDao;
    @Autowired
    private BaseDaoI<UserOrg> orgDao;
    @Autowired
    private BaseDaoI<UserBasic> userDao;
    @Autowired
    private BaseDaoI<UserPartyCompany> userPartyCompanyDao;
    @Autowired
    private BaseDaoI<SecRole> secRoleDao;
    @Autowired
    private BaseDaoI<TapeRecord> tapeRecordDao;
    @Autowired
    private BaseDaoI<UserSecRoleRel> userSecRoleRelDao;
    @Autowired
    private BaseDaoI<SysBusiRecord> sysBusiRecordDao;
    @Autowired
    private BaseDaoI<RechargeRecord> rechargeRecordDao;
    @Autowired
    private BaseDaoI<SystemMessage> systemMessageDao;


    /**
     * 根据partyId直接查询数据库的企业信息
     *
     * @param partyId
     * @return
     */
    public UserPartyCompany getUserPartyCompanyByPartyId(long partyId) {
        List<UserPartyCompany> userPartyCompanies = null;
        String hql = "from UserPartyCompany where partyId = :partyId";
        HashMap params = new HashMap();
        params.put("partyId", partyId);
        userPartyCompanies = userPartyCompanyDao.find(hql, params);
        if (userPartyCompanies != null && userPartyCompanies.size() > 0) {
            return userPartyCompanies.get(0);
        }
        return null;
    }

    /**
     * 根据部门名称查询
     *
     * @param name
     * @return
     */
    @Override
    public List<UserOrg> getUserOrgByName(String name, Long orgId, Long partyId) {
        String hql = "from UserOrg where orgName = :orgName and partyId =:partyId and state=1";
        HashMap params = new HashMap();
        params.put("orgName", name);
        params.put("partyId", partyId);
        if (orgId != null) {
            hql += " and orgId <>:orgId";
            params.put("orgId", orgId);
        }
        List<UserOrg> usergs = orgDao.find(hql, params);
        if (usergs != null && usergs.size() > 0) {
            return usergs;
        }
        return null;
    }

    /**
     * 获取平台所有企业
     *
     * @return
     */
    public List<UserParty> getUserPartys() {
        String hql = "from UserParty where state = 1";
        List<UserParty> userPartys = partyDao.find(hql);
        if (!userPartys.isEmpty()) {
            return userPartys;
        }
        return null;
    }

    /**
     * 获取企业信息
     *
     * @param partyId
     * @return
     */
    public UserParty getUserPartyById(long partyId) {
        String jsonStr = RedisHelper.getParty(partyId);
        UserParty partyFDB = null;
        if (StringUtils.isNotBlank(jsonStr)) {
            partyFDB = JSONObject.parseObject(jsonStr, UserParty.class);
        } else {
            partyFDB = partyDao.get(UserParty.class, partyId);
            if (partyFDB != null) {
                RedisHelper.setParty(partyFDB.getPartyId(), JSONObject.toJSONString(partyFDB));
            }
        }
        return partyFDB;
    }


    /**
     * 对账号进行密码加密处理
     *
     * @param account
     */
    private void encryptAccount(UserBasic account) {
        String mim = Md5Util.Md5Encode(account.getPassword(), null);
        mim = Md5Util.Md5Encode(mim, null);
        account.setPassword(mim);
    }

    /**
     * 添加或者修改组织
     *
     * @param org
     */
    @Override
    public UserOrg saveUserOrg(UserOrg org) throws ViChatException {
        if (NumberUtils.isNullOrZero(org.getOrgId())) {
            if (NumberUtils.isNotNullOrZero(org.getParentId())) {
                UserOrg parentOrg = this.queryUserOrgByOrgId(org.getParentId());
                if (parentOrg != null) {
                    org.setParentId(parentOrg.getOrgId());
                    org.setOrgCode(parentOrg.getOrgCode());
                    String orgCode = this.getOrgCode(org);
                    org.setOrgCode(orgCode);
                }
            } else {
                String orgCode = this.getOrgCode(org);
                org.setOrgCode(orgCode);
            }

            orgDao.save(org);
            this.updateUserOrgVersion(org.getOrgId());
            RedisHelper.setOrg(org.getOrgId(), JSONObject.toJSONString(org));
        } else {
            UserOrg orgFDB = orgDao.get(UserOrg.class, org.getOrgId());
            if (orgFDB != null) {
                orgFDB.setOrgName(org.getOrgName());
                orgFDB.setSortno(org.getSortno());
                orgFDB.setParentId(org.getParentId());
            }
            orgDao.update(orgFDB);
            this.updateUserOrgVersion(orgFDB.getOrgId());
            RedisHelper.setOrg(orgFDB.getOrgId(), JSONObject.toJSONString(orgFDB));
        }
        return org;
    }


    /**
     * 获取组织编号
     *
     * @param org
     * @return
     */
    private String getOrgCode(UserOrg org) {
        StringBuilder sql = new StringBuilder();
        if (NumberUtils.isNullOrZero(org.getParentId())) {
            sql.append("select LPAD(max(org_code+1),6,0) ID from user_org where parent_id=0");
        } else {
            sql.append("select concat(MIN(t.org_code),substr(concat('00',substr(MAX(t.org_code),length(MIN(t.org_code))+1,3)+1),length(concat('00',substr(MAX(t.org_code),length(MIN(t.org_code))+1,3)+1))-2,3)) ID from user_org t where t.org_code like '");
            sql.append(org.getOrgCode()).append("%'");
        }
        String orgCode = (String) orgDao.executeQueryBasic(sql.toString(), "ID", StringType.INSTANCE);
        if (StringUtils.isBlank(orgCode)) {
            orgCode = "000001";
        }
        return orgCode;
    }

    /**
     * 查询组织接口
     *
     * @param queryBean
     * @param pf
     * @return
     */
    @Override
    public List<UserOrg> queryUserOrgs(UserOrg queryBean, PageFilter pf) {
        String hql = "from UserOrg where state = 1";
        HashMap params = new HashMap();
        List<UserOrg> userOrgs = orgDao.find(hql + orgWhereHql(queryBean, params) + orderHql(pf), params, pf.getPage(), pf.getLimit());
        if (!userOrgs.isEmpty()) {
            for (UserOrg org : userOrgs) {
                if (NumberUtils.isNotNullOrZero(org.getParentId())) {
                    UserOrg orgFDB = queryUserOrgByOrgId(org.getParentId());
                    if (orgFDB != null) {
                        org.setParentName(orgFDB.getOrgName());
                    }
                }
            }
        }
        return userOrgs;
    }


    /**
     * 查询组织数量
     *
     * @param queryBean
     * @return
     */
    public Long countUserOrgs(UserOrg queryBean) throws Exception {
        String hql = "select count(*) from UserOrg where state = 1";
        Map<String, Object> params = new HashMap<String, Object>();
        return orgDao.count(hql + orgWhereHql(queryBean, params), params);
    }

    /**
     * 拼装组装条件
     *
     * @param bean
     * @param params
     * @return
     */
    private String orgWhereHql(UserOrg bean, Map<String, Object> params) {
        String hql = "";
        if (bean != null) {
            if (StringUtils.isNotBlank(bean.getOrgName())) {
                hql += " and orgName like :orgName";
                params.put("orgName", "%" + bean.getOrgName() + "%");
            }
            if (NumberUtils.isNotNullOrZero(bean.getPartyId())) {
                hql += " and partyId = :partyId";
                params.put("partyId", bean.getPartyId());
            }
            if (NumberUtils.isNotNullOrZero(bean.getVersion())) {
                hql += " and version > :version";
                params.put("version", bean.getVersion());
            }
            /*if (NumberUtils.isNotNullOrZero(bean.getParentId())) {
                hql += " and (orgId = :orgId or parentId = :parentId)";
                params.put("orgId", bean.getParentId());
                params.put("parentId", bean.getParentId());
            }*/
            if (NumberUtils.isNotNullOrZero(bean.getOrgId())) {
                UserOrg orgFDB = this.queryUserOrgByOrgId(bean.getOrgId());
                if (orgFDB.getParentId() != 0) {
                    hql += " and orgCode like :orgCode";
                    params.put("orgCode", orgFDB.getOrgCode() + "%");
                }
            }
            if (NumberUtils.isNotNullOrZero(bean.getParentId())) {
                UserOrg userOrg = orgDao.get(UserOrg.class, bean.getParentId());
                if (userOrg != null) {
                    hql += " and orgCode like :orgCode";
                    params.put("orgCode", "%" + userOrg.getOrgCode() + "%");
                }
            }
        }
        return hql;
    }


    /**
     * 拼装排序字段
     *
     * @param pf
     * @return
     */
    private String orderHql(PageFilter pf) {
        String orderString = "";
        if (pf != null) {
            if ((pf.getSort() != null) && (pf.getOrder() != null)) {
                orderString = " order by " + pf.getSort() + " " + pf.getOrder();
            }
        }
        return orderString;
    }

    /**
     * 根据组织编号查询组织,附加过滤
     *
     * @param orgCode
     * @return
     */
    public List<UserOrg> queryUserOrgsByOrgCodeC(String orgCode, String orgCodeName) {
        String hql = "from UserOrg where state = 1 and orgCode != :orgCodeName";
        HashMap params = new HashMap();
        params.put("orgCodeName", orgCodeName);

        if (StringUtils.isNotBlank(orgCode)) {
            hql += " and orgCode like :orgCode";
            params.put("orgCode", orgCode + "%");
        }
        List<UserOrg> userOrgs = orgDao.find(hql, params);
        return userOrgs;
    }

    /**
     * 根据组织查询可以修改的上级组织
     *
     * @param orgCode
     * @return
     */
    public List<UserOrg> queryParUserOrgsByOrgCodeC(String orgCode, String orgCodeName, long partyId) {
        String hql = "from UserOrg where state = 1 and orgCode != :orgCodeName";
        HashMap params = new HashMap();
        params.put("orgCodeName", orgCodeName);

        if (NumberUtils.isNotNullOrZero(partyId)) {
            hql += " and partyId = :partyId";
            params.put("partyId", partyId);
        }
        if (StringUtils.isNotBlank(orgCode)) {
            hql += " and orgCode not like :orgCode";
            params.put("orgCode", orgCodeName + "%");
        }
        List<UserOrg> userOrgs = orgDao.find(hql, params);
        return userOrgs;
    }

    /**
     * 根据组织编号查询组织
     *
     * @param orgCode
     * @return
     */
    public List<UserOrg> queryUserOrgsByOrgCode(String orgCode) {
        String hql = "from UserOrg where state = 1";
        HashMap params = new HashMap();
        if (StringUtils.isNotBlank(orgCode)) {
            hql += " and orgCode like :orgCode";
            params.put("orgCode", orgCode + "%");
        }
        List<UserOrg> userOrgs = orgDao.find(hql, params);
        return userOrgs;
    }

    /**
     * 根据组织ID获取组织信息
     *
     * @param orgId
     * @return
     */
    public UserOrg queryUserOrgByOrgId(long orgId) {
        String jsonStr = RedisHelper.getOrg(orgId);
        UserOrg orgFDB = null;
        if (StringUtils.isNotBlank(jsonStr)) {
            orgFDB = JSONObject.parseObject(jsonStr, UserOrg.class);
        } else {
            orgFDB = orgDao.get(UserOrg.class, orgId);
            if (orgFDB != null) {
                RedisHelper.setOrg(orgFDB.getOrgId(), JSONObject.toJSONString(orgFDB));
            }
        }
        return orgFDB;
    }

    public List<UserOrg> queryUserOrgsByParentId(long parentId) {
        UserOrg userOrgFDB = this.queryUserOrgByOrgId(parentId);

        String hql = "from UserOrg where state = 1";
        HashMap params = new HashMap();
        if (StringUtils.isNotBlank(userOrgFDB.getOrgCode())) {
            hql += " and orgCode like :orgCode";
            params.put("orgCode", userOrgFDB.getOrgCode() + "%");
        }
        List<UserOrg> userOrgs = orgDao.find(hql, params);
        UserOrg parentOrg = null;
        if (!userOrgs.isEmpty()) {
            for (UserOrg org : userOrgs) {
                if (org.getOrgId() == parentId) {
                    parentOrg = org;
                    break;
                }
            }
            if (parentOrg != null) {
                for (UserOrg org : userOrgs) {
                    if (org.getParentId() == parentId) {
                        org.setParentName(parentOrg.getOrgName());
                    } else if (NumberUtils.isNotNullOrZero(org.getParentId())) {
                        UserOrg grandParentOrg = this.queryUserOrgByOrgId(org.getParentId());
                        org.setParentName(grandParentOrg.getOrgName());
                    }
                }
            }
        }
        return userOrgs;
    }

    /**
     * 删除组织
     *
     * @param orgId
     */
    public void delUserOrg(long partyId, long orgId) throws ViChatException {
        UserOrg orgFDB = queryUserOrgByOrgId(orgId);
        if (orgFDB != null && orgFDB.getPartyId().longValue() == partyId) {
            if (countUserOrgByParentId(orgId) > 0) {
//                throw new RuntimeException("请先删除该组织的下属组织");
                String errorMsg = I18NUtil.getMessage("UserServiceImpl.saveUserOrg.error_childOrgIsExist", null, Locale.getDefault());
                throw new ViChatException(I18nConstant.error_childOrgIsExist, errorMsg);
            }
            if (countUserOrgByOrgCode(orgFDB.getOrgCode()) > 0) {
//                throw new RuntimeException("请先删除该组织下的用户");
                String errorMsg = I18NUtil.getMessage("UserServiceImpl.saveUserOrg.error_childOrgUserIsExist", null, Locale.getDefault());
                throw new ViChatException(I18nConstant.error_childOrgUserIsExist, errorMsg);
            }
            orgDao.delete(orgFDB);
            RedisHelper.delOrg(orgId);
        }
    }


    /**
     * 获取下属组织数量
     *
     * @param parentId
     * @return
     */
    private long countUserOrgByParentId(long parentId) {
        String hql = "select count(*) from UserOrg where state = 1 and parentId = :parentId";
        HashMap params = new HashMap();
        params.put("parentId", parentId);
        long count = orgDao.count(hql, params);
        return count;
    }


    /**
     * 获取组织下用户数量
     *
     * @param orgCode
     * @return
     */
    private long countUserOrgByOrgCode(String orgCode) {
        String hql = "select count(*) from UserBasic where state = 1 and orgCode = :orgCode";
        HashMap params = new HashMap();
        params.put("orgCode", orgCode);
        long count = userDao.count(hql, params);
        return count;
    }

    /**
     * 查询导出用户信息
     *
     * @param partyId
     * @param orgId
     * @param userType
     * @return
     */
    public List<UserBasic> queryUserBasics(Long partyId, Long orgId, Long userType) throws Exception {
        String hql = "from UserBasic where state in (1,9)";
        HashMap params = new HashMap();
        if (NumberUtils.isNotNullOrZero(partyId)) {
            hql += " and partyId = :partyId";
            params.put("partyId", partyId);
        }
        if (NumberUtils.isNotNullOrZero(orgId)) {
            UserOrg orgFDB = this.queryUserOrgByOrgId(orgId);
            if (orgFDB.getParentId() != 0) {
                hql += " and orgCode like :orgCode";
                params.put("orgCode", orgFDB.getOrgCode() + "%");
            }
        }
        if (NumberUtils.isNotNullOrZero(userType)) {
            hql += " and userType = :userType";
            params.put("userType", userType);
        }
        List<UserBasic> users = userDao.find(hql, params);
        return users;
    }


    /**
     * 查询用户信息
     *
     * @param queryBean
     * @param pf
     * @return
     */
    public List<UserBasic> queryUserBasics(UserBasic queryBean, PageFilter pf,boolean isPrecise) throws Exception {
        String hql = "from UserBasic where state in (1,9)";
        HashMap params = new HashMap();
        List<UserBasic> users = userDao.find(hql + userBasicWhereHql(queryBean, params,isPrecise) + PageFilter.orderHql(pf), params, pf.getPage(), pf.getLimit());

        return users;
    }

    /**
     * 查询用户信息
     *
     * @param queryBean
     * @param pf
     * @return
     */
    public List<UserBasicVO> queryUserBasicsBySql(UserBasic queryBean, PageFilter pf) throws Exception {
        String hql = "select uid as uid, user_number as userNumber, user_name as userName,  user_type as userType, sex  as sex, v_face  as vFace, terminal_type  as terminalType, terminal as terminal, phone as phone, password as password, short_number as shortNumber, imei as imei,  enabled as enabled,  a.state as state, a.create_time as createTime, a.update_time as updateTime, a.party_id  as partyId,  a.org_id as orgId, a.org_code as orgCode, visible  as visible, district_id  as districtId, district_type  as districtType, expired_date as expiredDate, iccid as iccid, app_version  as appVersion, display_state  as displayState,  loc_flag as locFlag,  loc_interval as locInterval, mobile as mobile, org_name  as orgName from userdb.user_basic a, userdb.user_org b where a.state in (1,9) and a.org_id = b.org_id ";
        HashMap params = new HashMap();
        List<UserBasicVO> users = userDao.findVoBySql(hql + userBasicWhereSql(queryBean, params) + PageFilter.orderHql(pf), params, UserBasicVO.class, pf.getPage(), pf.getLimit());

        return users;
    }

    /**
     * 查询用户信息
     *
     * @param queryBean
     * @param pf
     * @return
     */
    public List<UserBasicVO> queryUserBasicsBatch(UserBasic queryBean, PageFilter pf) throws Exception {
        String hql = "select uid as uid, user_name as userName,  org_name  as orgName from userdb.user_basic a, userdb.user_org b where a.state in (1,9) and a.org_id = b.org_id ";
        HashMap params = new HashMap();
        List<UserBasicVO> users = userDao.findVoBySql(hql + userBasicWhereSql(queryBean, params) + PageFilter.orderHql(pf), params, UserBasicVO.class, pf.getPage(), pf.getLimit());

        return users;
    }


    /**
     * 查询用户数量
     *
     * @param queryBean
     * @return
     */
    public Long countUserBasics(UserBasic queryBean,boolean isPrecise) throws Exception {
        String hql = "select count(*) from UserBasic where state in (1,9)";
        Map<String, Object> params = new HashMap<String, Object>();
        return userDao.count(hql + userBasicWhereHql(queryBean, params,isPrecise), params);
    }

    /**
     * 查询用户数量
     *
     * @param queryBean
     * @return
     */
    public BigInteger countUserBasicsBySql(UserBasic queryBean) throws Exception {
        String hql = "select count(*) from userdb.user_basic a, userdb.user_org b where a.state in (1,9) and a.org_id = b.org_id ";
        Map<String, Object> params = new HashMap<String, Object>();
        return userDao.countBySql(hql + userBasicWhereSql(queryBean, params), params);
    }


    /**
     * 拼装用户条件
     *
     * @param bean
     * @param params
     * @return
     */
    private String userBasicWhereHql(UserBasic bean, Map<String, Object> params,boolean isPrecise) throws Exception {
        String hql = "";
        if (bean != null) {
            if (NumberUtils.isNotNullOrZero(bean.getUid())) {
                hql += " and uid = :uid";
                params.put("uid", bean.getUid());
            }

            if (StringUtils.isNotBlank(bean.getUserName())) {
                if(isPrecise){
                    hql += " and userName like :userName";
                    params.put("userName", "%" + URLDecoder.decode(bean.getUserName(), "UTF-8") + "%");
                }else {
                    hql += " and (userName like :userName or imei like :userName or iccid like :userName or terminal like :userName or phone like :userName )";
                    params.put("userName", "%" + URLDecoder.decode(bean.getUserName(), "UTF-8") + "%");
                }
            }

            if (StringUtils.isNotBlank(bean.getUserNumber())) {
                hql += " and userNumber like :userNumber ";
                params.put("userNumber", "%" + bean.getUserNumber() + "%");
            }
            if (StringUtils.isNotBlank(bean.getPhone())) {
                hql += " and phone like :phone";
                params.put("phone", "%" + bean.getPhone() + "%");
            }
            if (StringUtils.isNotBlank(bean.getTerminal())) {
                hql += " and terminal = :terminal";
                params.put("terminal", "%" + bean.getTerminal() + "%");
            }
            if (StringUtils.isNotBlank(bean.getIccid())) {
                hql += " and  iccid like :iccid";
                params.put("iccid", "%" + bean.getIccid() + "%");
            }
            if (StringUtils.isNotBlank(bean.getImei())) {
                hql += " and  imei like :imei";
                params.put("imei", "%" + bean.getIccid() + "%");
            }
            if (NumberUtils.isNotNullOrZero(bean.getUserType())) {
                hql += " and userType = :userType";
                params.put("userType", bean.getUserType());
            }
            if (NumberUtils.isNotNullOrZero(bean.getPartyId())) {
                hql += " and partyId = :partyId";
                params.put("partyId", bean.getPartyId());
            }
            if (NumberUtils.isNotNullOrZero(bean.getLocFlag())) {
                hql += " and locFlag = :locFlag";
                params.put("locFlag", bean.getLocFlag());
            }
            if (bean.getStartDate() != null) {
                hql += " and expiredDate >= :startDate";
                params.put("startDate", bean.getStartDate());
            }
            if (bean.getEndDate() != null) {
                hql += " and expiredDate <= :endDate";
                params.put("endDate", bean.getEndDate());
            }
            if (NumberUtils.isNotNullOrZero(bean.getOrgId())) {
                UserOrg orgFDB = this.queryUserOrgByOrgId(bean.getOrgId());
                if (orgFDB.getParentId() != 0) {
                    hql += " and orgCode like :orgCode";
                    params.put("orgCode", orgFDB.getOrgCode() + "%");
                }
            }
            if (NumberUtils.isNotNull(bean.getVersion())) {
                hql += " and version > :version";
                params.put("version", bean.getVersion());
            }
        }
        return hql;
    }

    /**
     * 拼装用户条件
     *
     * @param bean
     * @param params
     * @return
     */
    private String userBasicWhereSql(UserBasic bean, Map<String, Object> params) throws Exception {
        String hql = "";
        if (bean != null) {
            if (NumberUtils.isNotNullOrZero(bean.getUid())) {
                hql += " and uid = :uid";
                params.put("uid", bean.getUid());
            }

            if (StringUtils.isNotBlank(bean.getUserName())) {
                hql += " and (user_name like :userName or imei like :userName or terminal like :userName )";
                params.put("userName", "%" + URLDecoder.decode(bean.getUserName(), "UTF-8") + "%");
            }

            if (StringUtils.isNotBlank(bean.getUserNumber())) {
                hql += " and user_number like :userNumber ";
                params.put("userNumber", "%" + bean.getUserNumber() + "%");
            }
            if (StringUtils.isNotBlank(bean.getPhone())) {
                hql += " and phone like :phone";
                params.put("phone", "%" + bean.getPhone() + "%");
            }
            if (StringUtils.isNotBlank(bean.getTerminal())) {
                hql += " and terminal = :terminal";
                params.put("terminal", "%" + bean.getTerminal() + "%");
            }
            if (StringUtils.isNotBlank(bean.getIccid())) {
                hql += " and  iccid like :iccid";
                params.put("iccid", "%" + bean.getIccid() + "%");
            }
            if (StringUtils.isNotBlank(bean.getImei())) {
                hql += " and  imei like :imei";
                params.put("imei", "%" + bean.getIccid() + "%");
            }
            if (NumberUtils.isNotNullOrZero(bean.getUserType())) {
                hql += " and user_type = :userType";
                params.put("userType", bean.getUserType());
            }
            if (NumberUtils.isNotNullOrZero(bean.getPartyId())) {
                hql += " and a.party_id = :partyId";
                params.put("partyId", bean.getPartyId());
            }
            if (NumberUtils.isNotNullOrZero(bean.getLocFlag())) {
                hql += " and loc_flag = :locFlag";
                params.put("locFlag", bean.getLocFlag());
            }
            if (bean.getStartDate() != null) {
                hql += " and expired_date >= :startDate";
                params.put("startDate", bean.getStartDate());
            }
            if (bean.getEndDate() != null) {
                hql += " and expired_date <= :endDate";
                params.put("endDate", bean.getEndDate());
            }
            if (NumberUtils.isNotNullOrZero(bean.getOrgId())) {
                UserOrg orgFDB = this.queryUserOrgByOrgId(bean.getOrgId());
                if (orgFDB.getParentId() != 0) {
                    hql += " and a.org_code like :orgCode";
                    params.put("orgCode", orgFDB.getOrgCode() + "%");
                }
            }
            if (NumberUtils.isNotNull(bean.getVersion())) {
                hql += " and a.version > :version";
                params.put("version", bean.getVersion());
            }
        }
        return hql;
    }

    /**
     * 根据用户编号(警号、工号、罪犯编号)查询用户信息
     *
     * @param userBasic
     * @return
     */
    private List<UserBasic> getUserBasicByNumber(UserBasic userBasic) {
        String hql = "from UserBasic where state in (1,9) and userNumber =:userNumber";
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("userNumber", userBasic.getUserNumber());
        if (userBasic.getUid() != null) {
            hql += " and uid !=:uid";
            map.put("uid", userBasic.getUid());
        }
        List<UserBasic> dataBasics = userDao.find(hql, map);

        return dataBasics;
    }

    /**
     * 根据用户姓名查询用户信息
     *
     * @param userBasic
     * @return
     */
    public List<UserBasic> getUserBasicByName(UserBasic userBasic) {
        String hql = "from UserBasic where state in (1,9) and userName =:userName and partyId =:partyId ";
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("userName", userBasic.getUserName());
        map.put("partyId", userBasic.getPartyId());

        if (userBasic.getUid() != null) {
            hql += " and uid !=:uid";
            map.put("uid", userBasic.getUid());
        }
        List<UserBasic> dataBasics = userDao.find(hql, map);
        return dataBasics;
    }

    public UserBasic getUserBasicByName(String userName) {
        String hql = "from UserBasic where state in (1,9) and userName =:userName";
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("userName", userName);

        List<UserBasic> dataBasics = userDao.find(hql, map);
        if (dataBasics != null && dataBasics.size() > 0) {
            return dataBasics.get(0);
        }
        return null;
    }


    /**
     * 根据警务通编号查询用户信息
     *
     * @param phone
     * @return
     */
    public UserBasic getUserBasicByPhone(String phone) {
        String hql = "from UserBasic where state in (1,9) and phone = :phone";
        HashMap params = new HashMap();
        params.put("phone", phone);
        List<UserBasic> users = userDao.find(hql, params);
        if (users != null && users.size() > 0) {
            return users.get(0);
        }
        return null;
    }


    /**
     * 根据uid获取用户信息
     *
     * @param uid
     * @return
     */
    public UserBasic getUserBasicByUid(long uid) {
        String jsonStr = RedisHelper.getUser(uid);
        UserBasic userFDB = null;
        if (StringUtils.isNotBlank(jsonStr)) {
            userFDB = JSONObject.parseObject(jsonStr, UserBasic.class);
        } else {

            userFDB = queryUserBasicByUid(uid);
            if (userFDB != null) {
                RedisHelper.setUser(userFDB.getUid(), JSONObject.toJSONString(userFDB));
            }
        }
        return userFDB;
    }

    public UserBasic queryUserBasicByUid(long uid) {
        String hql = "from UserBasic where state in (1,9) and uid = " + uid;
        List<UserBasic> userBasicList = userDao.find(hql);
        if (userBasicList != null && userBasicList.size() > 0) {
            return userBasicList.get(0);
        }
        return null;
    }

    /**
     * 根据userNumber获取用户信息
     *
     * @param userNumber
     * @return
     */
    public UserBasic getUserBasicByUserNumber(String userNumber) {
        String hql = "from UserBasic where userNumber =:userNumber and state in (1,9)";
        HashMap params = new HashMap();
        params.put("userNumber", userNumber);
        List<UserBasic> users = userDao.find(hql, params);
        if (users != null && users.size() > 0) {
            return users.get(0);
        }
        return null;
    }

    /**
     * 保存或者修改用户信息
     *
     * @param user
     * @return
     */
    public UserBasic saveUserBasic(UserBasic user) throws Exception {

        if (NumberUtils.isNullOrZero(user.getUid())) {//新增
            if (StringUtils.isBlank(user.getPassword())) {
                user.setPassword("111111");
            }
            //账号重复验证
            if (StringUtils.isNotBlank(user.getTerminal())) {
                boolean isTerminalExist = this.isTerminalExist(user.getTerminal());
                if (isTerminalExist) {
                    String errorMsg = I18NUtil.getMessage("error_accountIsExist", null, Locale.CHINA);
                    throw new ViChatException(I18nConstant.error_accountIsExist, errorMsg);
                }
            }
            if (StringUtils.isNotBlank(user.getIccid())) {
                boolean isIccidExist = this.isIccidExist(user.getIccid());
                if (isIccidExist) {
                    String errorMsg = I18NUtil.getMessage("error_ICCIDIsExist", null, Locale.CHINA);
                    throw new ViChatException(I18nConstant.error_ICCIDIsExist, errorMsg);
                }
                user.setTerminal(user.getIccid());
            }
            if (StringUtils.isNotBlank(user.getImei())) {
                boolean isImeiExist = this.isImeiExist(user.getImei());
                if (isImeiExist) {
                    String errorMsg = I18NUtil.getMessage("error_IMEIIsExist", null, Locale.CHINA);
                    throw new ViChatException(I18nConstant.error_IMEIIsExist, errorMsg);
                }
                user.setTerminal(user.getImei());
            }
            if (StringUtils.isBlank(user.getTerminal()) && StringUtils.isBlank(user.getIccid()) && StringUtils.isBlank(user.getImei())) {
                String errorMsg = I18NUtil.getMessage("error_parameter", null, Locale.CHINA);
                throw new ViChatException(I18nConstant.error_parameter, errorMsg);
            }

            String mim = Md5Util.Md5Encode(Md5Util.Md5Encode(user.getPassword(), null), null);
            UserOrg orgFDB = queryUserOrgByOrgId(user.getOrgId());
            user.setOrgCode(orgFDB.getOrgCode());
            user.setPassword(mim);

            String jsonStr = RedisHelper.getPartyCompany(user.getPartyId());
            UserPartyCompany company = null;
            if (StringUtils.isNotBlank(jsonStr)) {
                company = JSONObject.parseObject(jsonStr, UserPartyCompany.class);
            } else {
                company = getUserPartyCompanyByPartyId(user.getPartyId());
            }

            if (company.getFreeType() == GlobalConstant.FREE_TYPE_0) {
                user.setExpiredDate(DateUtil.getDateByString("2038-01-01", "yyyy-MM-dd"));
            } else {
                if (user.getExpiredDate() == null) {
                    user.setExpiredDate(DateUtil.getTodayTime("yyyy-MM-dd"));
                }
            }
            userDao.save(user);
//            this.updateUserBasicVersion(user.getUid());
            RedisHelper.setUser(user.getUid(), JSONObject.toJSONString(user));
            //判断用户类型,分配角色
            changeUserTypeRole(user);

            return user;
        } else {//修改
            UserBasic userFDB = queryUserBasicByUid(user.getUid());
            if (userFDB == null) {
//                throw new Exception("uid:" + user.getUid() + " 的用户不存在");
                String errorMsg = I18NUtil.getMessage("RoomApiController.getRooms.error_userNotExist", null, Locale.getDefault());
                throw new ViChatException(I18nConstant.error_userNotExist, errorMsg);
            }
            if (userFDB.getPartyId().longValue() != user.getPartyId().longValue()) {
                throw new Exception("参数partyId数据异常");
            }

            //企业级管理员不可修改用户类型，也不可被改成企业级管理员
//            if (userFDB.getUserType() != GlobalConstant.USER_TYPE_1 && user.getUserType() != GlobalConstant.USER_TYPE_1) {
//                userFDB.setUserType(user.getUserType());
//            }

            userFDB.setUserName(user.getUserName());
            userFDB.setSex(user.getSex());
            userFDB.setPhone(user.getPhone());
            userDao.update(userFDB);
//            this.updateUserBasicVersion(userFDB.getUid());
            RedisHelper.setUser(userFDB.getUid(), JSONObject.toJSONString(userFDB));

            //判断用户类型,分配角色
            if (userFDB.getUserType() != user.getUserType()) {
                changeUserTypeRole(user);
            }
            return userFDB;

        }

    }

    private void changeUserTypeRole(UserBasic userBasic) {
        if (NumberUtils.isNotNullOrZero(userBasic.getUserType())) {
            if (userBasic.getUserType() == GlobalConstant.USER_TYPE_4) {
                this.saveUserSecRoleRel(userBasic.getUid(), 3L);
            }
        }
    }


    protected UserSecRoleRel getUserSecRoleRelByUid(Long uid) {
        String hql = "from UserSecRoleRel where uid = :uid";
        HashMap params = new HashMap();
        params.put("uid", uid);
        List<UserSecRoleRel> querBeans = userSecRoleRelDao.find(hql, params);
        if (null != querBeans && querBeans.size() > 0) {
            return querBeans.get(0);
        }
        return null;
    }

    public void saveUserSecRoleRel(Long uid, Long roid) {
        //增加对应关系
        UserSecRoleRel roleRole = getUserSecRoleRelByUid(uid);
        if (roleRole != null) {
            roleRole.setRoid(roid);
            roleRole.setUpdateTime(new Date());
            roleRole.setCreateTime(new Date());
            userSecRoleRelDao.save(roleRole);
        } else {
            roleRole = new UserSecRoleRel();
            roleRole.setRoid(roid);
            roleRole.setUid(uid);
            roleRole.setState(1L);
            roleRole.setUpdateTime(new Date());
            roleRole.setCreateTime(new Date());
            userSecRoleRelDao.save(roleRole);
        }
    }


    /**
     * 删除用户信息
     *
     * @param uid
     */
    public void delUserBasic(long partyId, long uid) throws Exception {
        UserBasic userFDB = this.queryUserBasicByUid(uid);
        if (userFDB != null && partyId == userFDB.getPartyId()) {
            //解绑用户
            userFDB.setTerminal("");
            userFDB.setPhone("");
            userFDB.setImei("");
            userFDB.setShortNumber("");
            userFDB.setEnabled(GlobalConstant.DISABLE);
            userFDB.setState(GlobalConstant.DISABLE);
            userDao.update(userFDB);
            this.updateUserBasicVersion(userFDB.getUid());
            RedisHelper.delUser(uid);
            delResRoleUserRel(uid);
        }
    }

    /**
     * 物理删除用户与角色关系
     *
     * @param uid
     */
    private void delResRoleUserRel(Long uid) {
        UserSecRoleRel roleRel = getUserSecRoleRelByUid(uid);
        if (roleRel != null) {
            String sql = "delete from userdb.user_sec_role_rel where uid = :uid";
            HashMap params = new HashMap();
            params.put("uid", uid);
            userSecRoleRelDao.executeSql(sql, params);
        }
    }

    /**
     * 企业注册
     *
     * @param party
     * @param company
     * @param user
     * @throws Exception
     */
    public void registerPartyCompany(UserParty party, UserPartyCompany company, UserBasic user) throws Exception {
        this.checkIsAccountExist(user.getTerminal());
        //保存企业
        party.setPartyName(company.getCompanyName());
        //企业服务码
        String partyKey = UUID.randomUUID().toString().replaceAll("-", "").replaceAll("[a-zA-Z]", "").substring(0, 8);
        party.setPartyKey(partyKey);
        partyDao.save(party);
        RedisHelper.setParty(party.getPartyId(), JSONObject.toJSONString(party));
        //创建公司
        company.setPartyId(party.getPartyId());
        company.setFreeType(GlobalConstant.FREE_TYPE_1);// 收费，按用户失效期收费
        userPartyCompanyDao.save(company);
        RedisHelper.setPartyCompany(party.getPartyId(), JSONObject.toJSONString(company));
        //创建默认组织
        UserOrg org = new UserOrg();
        org.setOrgName(company.getCompanyName());
        org.setPartyId(party.getPartyId());
        String orgCode = this.getOrgCode(org);
        org.setOrgCode(orgCode);
        orgDao.save(org);
        this.updateUserOrgVersion(org.getOrgId());
        RedisHelper.setOrg(org.getOrgId(), JSONObject.toJSONString(org));
        encryptAccount(user);

        //保存登陆账号
        user.setUserType(GlobalConstant.USER_USER_TYPE_OWNER_1);
        user.setPartyId(party.getPartyId());
        user.setOrgId(org.getOrgId());
        user.setOrgCode(orgCode);
        user.setExpiredDate(DateUtil.getDateByString("2038-01-01", "yyyy-MM-dd"));
        userDao.save(user);
        this.updateUserBasicVersion(user.getUid());

        //增加对应关系
        UserSecRoleRel roleRole = new UserSecRoleRel();
        roleRole.setRoid(1L);
        roleRole.setUid(user.getUid());
        roleRole.setState(1L);
        roleRole.setUpdateTime(new Date());
        roleRole.setCreateTime(new Date());
        userSecRoleRelDao.save(roleRole);

        RedisHelper.setUser(user.getUid(), JSONObject.toJSONString(user));
    }

    /**
     * 判断账号是否已存在
     *
     * @param terminal
     */
    public void checkIsAccountExist(String terminal) throws ViChatException {
        UserBasic userBasic = getUserBasicByTerminal(terminal);
        if (userBasic != null) {
            String errorMsg = I18NUtil.getMessage("UserServiceImpl.checkIsAccountExist.error_AccountIsExist", null, Locale.CHINA);
            throw new ViChatException(I18nConstant.error_accountIsExist, errorMsg);
        }
    }

    @Override
    public UserBasic getUserBasicByTerminal(String terminal) {
        String hql = "from UserBasic where state in (1,9) and terminal = :terminal";
        HashMap params = new HashMap();
        params.put("terminal", terminal);
        List<UserBasic> users = userDao.find(hql, params);
        if (users != null && users.size() > 0) {
            return users.get(0);
        }
        return null;
    }

    @Override
    public List<UserBasic> queryUserBasicsByRoid(long roid) {
        String sql = "select a.* from user_basic a, user_sec_role_rel b where a.uid = b.uid and b.state = 1 and b.roid = :roid";
        HashMap params = new HashMap();
        params.put("roid", roid);
        return userDao.findEntityBySql(sql, params, UserBasic.class);
    }

    /**
     * 修改密码
     *
     * @param user
     * @throws Exception
     */
    public void updUserPwd(UserBasic user) throws Exception {
        UserBasic userBasic = queryUserBasicByUid(user.getUid());
        if (userBasic != null) {
            userBasic.setPassword(user.getPassword());
            userDao.update(userBasic);
            this.updateUserBasicVersion(userBasic.getUid());
        }
        RedisHelper.setUser(user.getUid(), JSONObject.toJSONString(userBasic));

    }

    /**
     * 根据职位名称查找职位
     *
     * @param roleName
     * @return
     */
    public List<SecRole> queryUserRoidByRoleName(String roleName) {
        String hql = "from SecRole where state = 1 and roleName = :roleName";
        HashMap params = new HashMap();
        params.put("roleName", roleName);

        List<SecRole> secRoles = secRoleDao.find(hql, params);
        if (!secRoles.isEmpty()) {
            return secRoles;
        }
        return null;
    }


    /**
     * 获取谈话录音
     *
     * @param queryBean
     * @param pf
     * @return
     */
    public List<TapeRecord> queryTapeRecord(TapeRecord queryBean, PageFilter pf) {
        Map<String, Object> params = new HashMap<>();
        String sql = "select record.* from tape_record record left join user_basic usr on usr.uid = record.uid "
                + " left join user_basic crim on crim.uid = record.uid  where 1=1 ";
        if (StringUtils.isNotEmpty(queryBean.getStartDateStr())) {
            Date startDate = DateUtil.StrToDate(queryBean.getStartDateStr());
            params.put("startTime", DateUtil.getDateStart(startDate));
            sql += " and record.upload_time >=:startTime";
        }
        if (StringUtils.isNotEmpty(queryBean.getEndDateStr())) {
            Date endDate = DateUtil.StrToDate(queryBean.getEndDateStr());
            params.put("endTime", DateUtil.getDateEnd(endDate));
            sql += " and record.upload_time >=:endTime";
        }
        if (StringUtils.isNotEmpty(queryBean.getCriminalName())) {
            params.put("criminalName", "%" + queryBean.getCriminalName() + "%");
            sql += " and crim.user_name like:criminalName";
        }
        if (StringUtils.isNotEmpty(queryBean.getPoliceName())) {
            params.put("policeName", "%" + queryBean.getPoliceName() + "%");
            sql += " and crim.user_name like:policeName";
        }
        @SuppressWarnings("unchecked")
        List<TapeRecord> districtLines = tapeRecordDao.findEntityBySql(sql, params, TapeRecord.class, pf.getPage(), pf.getLimit());
        return districtLines;
    }

    /**
     * 谈话记录总数
     *
     * @param queryBean
     * @return
     */
    public Long countqueryTapeRecord(TapeRecord queryBean) {
        HashMap<String, Object> params = new HashMap<>();
        String hql = "select count(*) from TapeRecord where 1=1  ";
        Long re = tapeRecordDao.count(hql, params);
        return re;
    }


    @Override
    public UserBasic getUserBasicByUid(long partyId, long uid) {
        String jsonUser = RedisHelper.getUser(uid);
        UserBasic user = null;
        if (StringUtils.isNotBlank(jsonUser)) {
            user = JSONObject.parseObject(jsonUser, UserBasic.class);
        } else {
            String hql = "from UserBasic where state in (1,9) and partyId = :partyId and uid = :uid";
            HashMap params = new HashMap();
            params.put("partyId", partyId);
            params.put("uid", uid);
            user = userDao.get(hql, params);
            if (user != null) {
                RedisHelper.setUser(uid, JSONObject.toJSONString(user));
            }
        }
        return user;
    }


    /**
     * 获取人员总览
     *
     * @return
     */
    public UserOnlineVO getUserOnlineView(UserBasic queryBean) {
        UserOnlineVO userOnlineVO = new UserOnlineVO();
        Long partyUserNum = getPartyUserNum(queryBean.getPartyId(), queryBean.getOrgCode());
        // Long onlineUserNum =
        // RedisHelper.getPartyOnlineNum(queryBean.getPartyId());
        Long onlineUserNum = this.getOnlineAndOfflineNum(queryBean.getPartyId(), queryBean.getOrgCode(), 1l);
        // 公司总人数
        userOnlineVO.setPartyUserNum(partyUserNum);
        // 在线人员
        userOnlineVO.setOnlineUserNum(onlineUserNum);
        // 离线人员
        userOnlineVO.setOfflineUserNum(partyUserNum - onlineUserNum);
        // 未登录人员
        userOnlineVO.setNoLoginUserNum(0l);
        // 休假人员
        userOnlineVO.setHolidayNum(0l);
        // 位置缺失人员
        userOnlineVO.setNoLocationNum(0l);
        // 位置共享人员
        userOnlineVO.setLocationSharNum(0l);
        return userOnlineVO;
    }

    /**
     * 获取公司总人数
     *
     * @param partyId
     * @return
     */
    public long getPartyUserNum(long partyId, String orgCode) {
        Map<String, Object> params = new HashMap<String, Object>();
        String hql = "select count(*) from UserBasic where state in (1,9)";
        if (NumberUtils.isNotNullOrZero(partyId)) {
            hql += " and partyId = :partyId";
            params.put("partyId", partyId);
        }
        if (StringUtils.isNotBlank(orgCode)) {
            hql += " and orgCode like :orgCode";
            params.put("orgCode", orgCode + "%");
        }
        return userDao.count(hql, params);
    }

    /**
     * 获取在线离信人员总数
     *
     * @param partyId
     * @param orgCode
     * @param displayState 0 离线 7 在线
     * @return
     */
    private long getOnlineAndOfflineNum(long partyId, String orgCode, long displayState) {
        Map<String, Object> params = new HashMap<String, Object>();
        String hql = "select count(*) from UserBasic where state in (1,9)";
        if (NumberUtils.isNotNullOrZero(partyId)) {
            hql += " and partyId = :partyId";
            params.put("partyId", partyId);
        }
        if (NumberUtils.isNotNullOrZero(displayState)) {
            hql += " and displayState = :displayState";
            params.put("displayState", displayState);
        }
        if (StringUtils.isNotBlank(orgCode)) {
            hql += " and orgCode like :orgCode";
            params.put("orgCode", orgCode + "%");
        }
        return userDao.count(hql, params);
    }


    /**
     * 查询组织数量
     *
     * @param queryBean
     * @return
     */
    public Long countUserOrgsApi(UserOrg queryBean) throws Exception {
        String hql = "select count(*) from UserOrg where 1 = 1";
        Map<String, Object> params = new HashMap<String, Object>();
        return orgDao.count(hql + orgWhereHql(queryBean, params), params);
    }


    /**
     * 查询组织
     *
     * @param queryBean
     * @param pf
     * @return
     */
    public List<UserOrg> queryUserOrgsApi(UserOrg queryBean, PageFilter pf) {
        String hql = "from UserOrg where 1 = 1";
        HashMap params = new HashMap();
        List<UserOrg> userOrgs = orgDao.find(hql + orgWhereHql(queryBean, params) + orderHql(pf), params, pf.getPage(), pf.getLimit());
        if (!userOrgs.isEmpty()) {
            for (UserOrg org : userOrgs) {
                if (NumberUtils.isNotNullOrZero(org.getParentId())) {
                    UserOrg orgFDB = queryUserOrgByOrgId(org.getParentId());
                    if (orgFDB != null) {
                        org.setParentName(orgFDB.getOrgName());
                    }
                }
            }
        }
        return userOrgs;
    }


    /**
     * 查询用户信息Api接口
     *
     * @param queryBean
     * @param pf
     * @return
     */
    public List<UserVO> queryApiUserBasics(UserBasic queryBean, PageFilter pf) throws Exception {
        String hql = "from UserBasic where 1 = 1";
        HashMap params = new HashMap();
        List<UserBasic> users = userDao.find(hql + userBasicWhereHql(queryBean, params,false) + PageFilter.orderHql(pf), params, pf.getPage(), pf.getLimit());
        List<UserVO> userVOs = new ArrayList<>();
        if (!users.isEmpty()) {
            for (UserBasic user : users) {
                UserVO userVO = new UserVO();
                userVO.setUid(user.getUid());
                userVO.setUserNumber(user.getUserNumber());
                if (StringUtils.isNotBlank(user.getTerminal())) {
                    userVO.setTerminal(user.getTerminal());
                }
                userVO.setUserName(user.getUserName());
                userVO.setUserType(user.getUserType());
                userVO.setSex(user.getSex());
                userVO.setvFace(user.getVFace());
                userVO.setPhone(user.getPhone());
                userVO.setState(user.getState());
                userVO.setVersion(user.getVersion());
                userVO.setPartyId(user.getPartyId());
                userVO.setOrgId(user.getOrgId());
                userVO.setVisible(user.getVisible());
                userVOs.add(userVO);
            }
        }
        return userVOs;
    }

    public List<UserBasic> getOnlineUsers(UserBasic queryBean) {
        HashMap params = new HashMap();
        String hql = "from UserBasic where state in (1,9)";
        if (NumberUtils.isNotNullOrZero(queryBean.getPartyId())) {
            hql += " and partyId = :partyId";
            params.put("partyId", queryBean.getPartyId());
        }
        if (StringUtils.isNotBlank(queryBean.getOrgCode())) {
            hql += " and orgCode like :orgCode";
            params.put("orgCode", queryBean.getOrgCode() + "%");
        }
        if (NumberUtils.isNotNullOrZero(queryBean.getDisplayState())) {
            hql += " and displayState = :displayState";
            params.put("displayState", queryBean.getDisplayState());
        }
        List<UserBasic> users = userDao.find(hql, params);
        return users;
    }

    public void updateLocationFlag(Long uid, Long flag, Long interval) {
        UserBasic userBasic = queryUserBasicByUid(uid);
        if (userBasic != null) {
            userBasic.setLocFlag(flag);
            userBasic.setLocInterval(interval);
            userDao.update(userBasic);
            this.updateUserBasicVersion(userBasic.getUid());
            RedisHelper.setUser(userBasic.getUid(), JSONObject.toJSONString(userBasic));
        }
    }

    public void saveUserOrg(UserBasic userFDB, Long orgId) {
        UserOrg orgFDB = orgDao.get(UserOrg.class, orgId);
        if (userFDB != null && orgFDB != null) {
            if (userFDB.getUserType() != GlobalConstant.USER_TYPE_1) {// 默认企业管理员不允许修改组织、用户类型。
                userFDB.setPartyId(orgFDB.getPartyId());
                userFDB.setOrgCode(orgFDB.getOrgCode());
                userFDB.setOrgId(orgFDB.getOrgId());
                userDao.update(userFDB);
                this.updateUserBasicVersion(userFDB.getUid());
                RedisHelper.setUser(userFDB.getUid(), JSONObject.toJSONString(userFDB));
            }
        }
    }

    /**
     * 注册(公司类型)接口，无须管理员账号
     */
    public CompanyVO registerCompanyNoAdmin(String companyName, String sourceId, long appId) {
        UserParty party = new UserParty();
        party.setPartyName(companyName);
        String partyKey = UUID.randomUUID().toString().replace("-", "");
        party.setPartyKey(partyKey);
        partyDao.save(party);
        // 将party对象放到redis
        RedisHelper.setParty(party.getPartyId(), JSONObject.toJSONString(party));
        long partyId = party.getPartyId();
        UserPartyCompany company = new UserPartyCompany();
        company.setCompanyName(companyName);
        company.setPartyId(partyId);
        company.setFreeType(GlobalConstant.FREE_TYPE_1);// 收费，按用户失效期收费
        company.setCompanyAddress(sourceId);
        userPartyCompanyDao.save(company);
        RedisHelper.setPartyCompany(company.getCompanyId(), JSONObject.toJSONString(company));
        // 创建默认公司组织
        UserOrg org = new UserOrg();
        org.setOrgName(company.getCompanyName());
        org.setPartyId(partyId);
        String orgCode = this.getOrgCode(org);
        org.setOrgCode(orgCode);
        orgDao.save(org);
        this.updateUserOrgVersion(org.getOrgId());
        RedisHelper.setOrg(org.getOrgId(), JSONObject.toJSONString(org));
        // 将公司相关信息放到Redis
        CompanyVO edposCompanyVO = new CompanyVO();
        edposCompanyVO.setParty(party);
        edposCompanyVO.setCompany(company);
        edposCompanyVO.setOrg(org);
//        RedisHelper.setCompanyVO(partyId, JSONObject.toJSONString(edposCompanyVO));
//        RedisHelper.setCompanyVO(partyKey, JSONObject.toJSONString(edposCompanyVO));
        return edposCompanyVO;
    }


    public boolean isIccidExist(String iccid) {
        boolean flag = false;
        String hql = "from UserBasic where state in (1,9) and (iccid = :iccid or terminal = :iccid)";
        HashMap params = new HashMap();
        params.put("iccid", iccid);
        List<UserBasic> users = userDao.find(hql, params);
        if (users != null && users.size() > 0) {
            flag = true;
        }
        return flag;
    }

    public boolean isImeiExist(String imei) {
        boolean flag = false;
        String hql = "from UserBasic where state in (1,9) and (imei = :imei or terminal = :imei)";
        HashMap params = new HashMap();
        params.put("imei", imei);
        List<UserBasic> users = userDao.find(hql, params);
        if (users != null && users.size() > 0) {
            flag = true;
        }
        return flag;
    }

    public Boolean isTerminalExist(String terminal) {
        UserBasic userBasicFDB = getUserBasicByTerminal(terminal);
        if (userBasicFDB != null) {
            return true;
        }
        return false;
    }

    /**
     * 根据partyId获取默认组织编号
     *
     * @param partyId
     * @return
     */
    public UserOrg getRootOrgByPartyId(long partyId) {
        String hql = "from UserOrg where state = 1 and partyId = :partyId and parent_id = 0";
        HashMap params = new HashMap();
        params.put("partyId", partyId);
        return orgDao.get(hql, params);
    }


    public UserBasic activateUser(long partyId, long uid, Date expiredDate) throws Exception {
        UserBasic userFDB = getUserBasicByUid(partyId, uid);
        if (userFDB != null) {
            if (userFDB.getPartyId().longValue() != partyId) {
                throw new Exception("partyId与uid不匹配");
            }
            userFDB.setExpiredDate(expiredDate);
            userDao.update(userFDB);
            this.updateUserBasicVersion(userFDB.getUid());
            RedisHelper.setUser(uid, JSONObject.toJSONString(userFDB));
        }
        return userFDB;
    }

    /**
     * 获取用户列表
     *
     * @param partyId
     * @param sort
     * @param order
     * @return
     */
    public List<UserBasic> getUserBasicsByPartyId(long partyId, String sort, String order) {
        String hql = "from UserBasic where state in (1,9) and partyId = :partyId";
        HashMap params = new HashMap();
        params.put("partyId", partyId);
        if (StringUtils.isNotBlank(sort) && StringUtils.isNotBlank(order)) {
            hql += " order by " + sort + " " + order;
        }
        List<UserBasic> list = userDao.find(hql, params);
        if (list.size() > 0) {
            return list;
        }
        return null;
    }

    /**
     * 保存操作日志
     *
     * @param user
     * @param type
     * @param opedUid
     * @param opedUserName
     * @param opedInfo
     * @param remark
     * @throws Exception
     */
    public void saveSysBusiRecord(UserBasic user, RecordType type, long opedUid, String opedUserName, String opedInfo, String remark) {
        try {
            SysBusiRecord busiRecord = new SysBusiRecord();
            if (user != null) {
                busiRecord.setUid(user.getUid());
                busiRecord.setUserName(user.getUserName());
                busiRecord.setPartyId(user.getPartyId());
                busiRecord.setOrgId(user.getOrgId());
                busiRecord.setOrgCode(user.getOrgCode());
                busiRecord.setOrgName(user.getOrgName());
            }
            busiRecord.setOpedType(type.getCode());
            busiRecord.setOpedUid(opedUid);
            busiRecord.setOpedUserName(opedUserName);
            busiRecord.setOpedInfo(opedInfo);
            busiRecord.setRemark(remark);
            sysBusiRecordDao.save(busiRecord);
        } catch (Exception e) {
            logger.error("保存操作日志失败");
        }
    }

    /**
     * 根据条件查询角色信息
     *
     * @param uid
     * @return
     */
    public List<SecRole> querySecRoleByUid(Long uid) {
        String sql = "select a.* from sec_role a, user_sec_role_rel b where a.roid = b.roid and b.uid = :uid";
        HashMap params = new HashMap();
        params.put("uid", uid);
        List<SecRole> secRoleList = secRoleDao.findEntityBySql(sql, params, SecRole.class);
        return secRoleList;
    }

    public UserPartyCompany getUserPartyCompanyByPartyId(Long partyId) {
        String jsonUserPartyCompany = RedisHelper.getPartyCompany(partyId);
        UserPartyCompany userPartyCompany = null;
        if (StringUtils.isNotBlank(jsonUserPartyCompany)) {
            userPartyCompany = JSONObject.parseObject(jsonUserPartyCompany, UserPartyCompany.class);
        } else {
            String hql = "from UserPartyCompany where partyId = :partyId";
            HashMap params = new HashMap();
            params.put("partyId", partyId);
            userPartyCompany = userPartyCompanyDao.get(hql, params);
            if (userPartyCompany != null) {
                RedisHelper.setPartyCompany(partyId, JSONObject.toJSONString(userPartyCompany));
            }
        }
        return userPartyCompany;
    }

    public List<UserBasic> getUserBasicsByOrgId(Long orgId) {
        String hql = "from UserBasic where state in (1,9) and orgId = :orgId";
        HashMap params = new HashMap();
        params.put("orgId", orgId);
        return userDao.find(hql, params);
    }

    public Map<String, List<UserBasic>> batchCreateUser(List<UserBasic> users) {
        Map<String, List<UserBasic>> rtnMap = new HashMap<String, List<UserBasic>>();
        List<UserBasic> successList = new ArrayList<UserBasic>();
        List<UserBasic> failList = new ArrayList<UserBasic>();
        // 批量导入用户初始密码6个1

        for (UserBasic user : users) {
            user.setUid(null);// 清空uid
            user.setUserType(GlobalConstant.USER_TYPE_3);
            user.setPassword("111111");
            try {
                this.saveUserBasic(user);
                successList.add(user);
            } catch (Exception e) {
                logger.error("batchCreateUser", e);
                e.printStackTrace();
                failList.add(user);
            }
        }
        rtnMap.put("SUCCESS_LIST", successList);
        rtnMap.put("FAIL_LIST", failList);
        return rtnMap;
    }

    /**
     * 根据组织编号orgId查询组织
     *
     * @param partyId
     * @param orgId
     * @return
     */
    @Override
    public UserOrg queryUserOrgByOrgId(long partyId, long orgId) {
        String hql = "from UserOrg where state = 1";
        HashMap params = new HashMap();
        if (NumberUtils.isNotNullOrZero(partyId)) {
            hql += " and partyId = :partyId";
            params.put("partyId", partyId);
        }
        hql += " and orgId = :orgId";
        params.put("orgId", orgId);
        UserOrg userOrg = orgDao.get(hql, params);
        if (userOrg.getParentId() > 0) {
            UserOrg parentOrg = orgDao.get(UserOrg.class, userOrg.getParentId());
            if (parentOrg != null)
                userOrg.setParentName(parentOrg.getOrgName());
        }
        return userOrg;
    }

    /**
     * 根据组织名称查询组织部门
     *
     * @param partyId
     * @param orgName
     * @return
     */
    @Override
    public List<UserOrg> queryUserOrgByOrgName(long partyId, String orgName) {
        String hql = "from UserOrg where state = 1 and partyId = :partyId and orgName = :orgName";
        HashMap params = new HashMap();
        params.put("partyId", partyId);
        params.put("orgName", orgName);
        List<UserOrg> edposOrgs = orgDao.find(hql, params);
        return edposOrgs;
    }

    public UserBasic getUserBasicByPartyId(long partyId, long userType) {
        String hql = "from UserBasic where state in (1,9) and partyId = :partyId and userType = :userType";
        HashMap params = new HashMap();
        params.put("partyId", partyId);
        params.put("userType", userType);
        List<UserBasic> list = userDao.find(hql, params);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    public void updateOnlineState(Long uid, Integer state) {
        logger.info("updateOnlineState:" + uid);
        UserBasic userBasic = queryUserBasicByUid(uid);
        //if(userBasic.getDisplayState() == null || userBasic.getDisplayState().intValue() != state){
        userBasic.setDisplayState(state.longValue());
        userDao.updateOnly(userBasic);
        this.updateUserBasicVersion(userBasic.getUid());
        RedisHelper.setUser(userBasic.getUid(), JSONObject.toJSONString(userBasic));
        //}
    }

    public BigInteger countExpiringUser(int day, UserCompanyVO queryBean) throws Exception {
        HashMap params = new HashMap();
        String hql = "select count(distinct a.uid) from userdb.user_basic a , userdb.user_party_company b ,userdb.user_org c where c.state = 1 and a.state in (1,9) and b.state = 1 and a.party_id = b.party_id and a.org_id = c.org_id ";
        return userDao.countBySql(hql + queryExpiringUserSql(params, queryBean, day), params);
    }

    public List<UserCompanyVO> queryExpiringUser(int day, UserCompanyVO queryBean, PageFilter pageFilter) throws Exception {
        HashMap params = new HashMap();
        String hql = "select a.uid,terminal,a.user_name as userName,user_type as userType, expired_date as expiredDate, c.org_name as orgName,b.company_name as companyName from userdb.user_basic a , userdb.user_party_company b,userdb.user_org c where c.state = 1 and  a.state in (1,9) and b.state = 1 and a.party_id = b.party_id and a.org_id = c.org_id ";
        return userDao.findVoBySql(hql + queryExpiringUserSql(params, queryBean, day), params, UserCompanyVO.class, pageFilter.getPage(), pageFilter.getRows());
    }

    private String queryExpiringUserSql(HashMap params, UserCompanyVO queryBean, int day) {
        Date expiredDate = DateUtil.addDay(DateUtil.getCalendarCurrentTimestamp(), day);

        String hql = " and a.expired_date > :startDate and a.expired_date <= :endDate ";
        params.put("startDate", new Date());
        params.put("endDate", expiredDate);

        if (NumberUtils.isNotNullOrZero(queryBean.getAgentId())) {
            hql += " and b.agent_id = :agentId ";
            params.put("agentId", queryBean.getAgentId());
        }
        if (NumberUtils.isNotNullOrZero(queryBean.getPartyId())) {
            hql += " and b.party_id = :partyId ";
            params.put("partyId", queryBean.getPartyId());
        }
        if (StringUtils.isNotBlank(queryBean.getCompanyName())) {
            hql += " and b.company_name like :companyName ";
            params.put("companyName", "%" + queryBean.getCompanyName() + "%");
        }
        if (StringUtils.isNotBlank(queryBean.getUserName())) {
            hql += " and a.user_name like :userName ";
            params.put("userName", "%" + queryBean.getUserName() + "%");
        }
        if (StringUtils.isNotBlank(queryBean.getTerminal())) {
            hql += " and a.terminal like :terminal ";
            params.put("terminal", "%" + queryBean.getTerminal() + "%");
        }
        return hql;
    }

    public BigInteger countExpiredUser(UserPartyCompany queryBean) throws Exception {
        HashMap params = new HashMap();
        String hql = "select count(distinct a.uid) from userdb.user_basic a , userdb.user_party_company b ,userdb.user_org c where c.state = 1 and a.state in (1,9) and b.state = 1 and a.party_id = b.party_id and a.org_id = c.org_id ";
        return userDao.countBySql(hql + queryExpiredUserHql(params, queryBean), params);
    }

    public List<UserCompanyVO> queryExpiredUser(UserPartyCompany queryBean, PageFilter pageFilter) throws Exception {
        HashMap params = new HashMap();
        String hql = "select terminal,a.user_name as userName,user_type as userType, expired_date as expiredDate, c.org_name as orgName from userdb.user_basic a , userdb.user_party_company b,userdb.user_org c where c.state = 1 and  a.state in (1,9) and b.state = 1 and a.party_id = b.party_id and a.org_id = c.org_id";
        return userDao.findVoBySql(hql + queryExpiredUserHql(params, queryBean), params, UserCompanyVO.class, pageFilter.getPage(), pageFilter.getRows());
    }

    private String queryExpiredUserHql(HashMap params, UserPartyCompany queryBean) {
        String hql = " and a.expired_date <= :startDate";
        params.put("startDate", DateUtil.getTodayTime("yyyy-MM-dd"));

        if (NumberUtils.isNotNullOrZero(queryBean.getAgentId())) {
            hql += " and b.agent_id = :agentId ";
            params.put("agentId", queryBean.getAgentId());
        }
        if (NumberUtils.isNotNullOrZero(queryBean.getPartyId())) {
            hql += " and b.party_id = :partyId ";
            params.put("partyId", queryBean.getPartyId());
        }
        return hql;
    }

    public long countEffetiveUser() {
        HashMap params = new HashMap();
        String hql = "select count(*) from UserBasic where state in (1,9) and expiredDate > :startDate";
        params.put("startDate", DateUtil.getTodayTime("yyyy-MM-dd"));
        return userDao.count(hql, params);
    }

    public long countEffetiveUserByPartyId(long partyId) {
        HashMap params = new HashMap();
        String hql = "select count(*) from UserBasic where state in (1,9) and userType <> 2 and expiredDate > :startDate and partyId = :partyId";
        params.put("startDate", DateUtil.getTodayTime("yyyy-MM-dd"));
        params.put("partyId", partyId);
        return userDao.count(hql, params);
    }
    public long countEffetiveUserExceptPartyAdminByPartyId(long partyId) {
        HashMap params = new HashMap();
        String hql = "select count(*) from UserBasic where state in (1,9) and userType <> 1 and expiredDate > :startDate and partyId = :partyId";
        params.put("startDate", DateUtil.getTodayTime("yyyy-MM-dd"));
        params.put("partyId", partyId);
        return userDao.count(hql, params);
    }
    public long countEffetiveTermianlUser() {
        HashMap params = new HashMap();
        String hql = "select count(*) from UserBasic where state in (1,9) and userType = 3 and expiredDate > :startDate";
        params.put("startDate", DateUtil.getTodayTime("yyyy-MM-dd"));
        return userDao.count(hql, params);
    }
    public long countEffetiveDispatcherUser() {
        HashMap params = new HashMap();
        String hql = "select count(*) from UserBasic where state in (1,9) and userType = 4 and expiredDate > :startDate";
        params.put("startDate", DateUtil.getTodayTime("yyyy-MM-dd"));
        return userDao.count(hql, params);
    }

    @Override
    public void stopUserBasic(long partyId, long uid) throws Exception {
        UserBasic userBasic = this.queryUserBasicByUid(uid);
        if (userBasic != null && userBasic.getPartyId() == partyId) {
            userBasic.setState(9l);
            userDao.update(userBasic);
            this.updateUserBasicVersion(userBasic.getUid());
            RedisHelper.setUser(userBasic.getUid(), JSONObject.toJSONString(userBasic));
        }
    }
    @Override
    public void startUserBasic(long partyId, long uid) throws Exception {
        UserBasic userBasic = this.queryUserBasicByUid(uid);
        if (userBasic != null && userBasic.getPartyId() == partyId) {
            userBasic.setState(1l);
            userDao.update(userBasic);
            this.updateUserBasicVersion(userBasic.getUid());
            RedisHelper.setUser(userBasic.getUid(), JSONObject.toJSONString(userBasic));
        }
    }

    @Override
    public void deleteCompany(long partyId) {
        UserPartyCompany company = this.getUserPartyCompanyByPartyId(partyId);
        if (company != null && company.getPartyId() == partyId) {

            if(company.getFreeType() == 1){
                //删除企业管理员
                this.deleteAdminUser(partyId);
            }
            else if(company.getFreeType() == 0){
                //删除企业下所有员工
                this.deleteAllPartyUser(partyId);
            }
            company.setState(0l);
            userPartyCompanyDao.update(company);
            RedisHelper.setPartyCompany(partyId,JSONObject.toJSONString(company));
        }


        UserParty userParty = this.getUserPartyById(partyId);
        if (userParty != null && userParty.getPartyId() == partyId) {
            userParty.setState(0l);
            partyDao.update(userParty);
            RedisHelper.setParty(partyId,JSONObject.toJSONString(userParty));
        }
    }

    public void updateUserBasicVersion(long uid){
        String hql = "update userdb.user_basic set  version = REPLACE(unix_timestamp(current_timestamp(3)),'.','')  where uid=" + uid;
        userDao.executeSql(hql);
    }
    public void updateUserBasicVersionByPartyId(long partyId){
        String hql = "update userdb.user_basic set  version = REPLACE(unix_timestamp(current_timestamp(3)),'.','')  where party_id=" + partyId;
        userDao.executeSql(hql);
    }
    public void updateUserOrgVersion(long orgId){
        String hql = "update userdb.user_org set  version = REPLACE(unix_timestamp(current_timestamp(3)),'.','')  where org_id="+orgId;
        orgDao.executeSql(hql);
    }

    public void deleteAdminUser(long partyId){
        String sql = "update userdb.user_basic set state = 0, version = REPLACE(unix_timestamp(current_timestamp(3)),'.','') where user_type in (1,2) and party_id = " + partyId;
        userDao.executeSql(sql);
    }
    public void deleteAllPartyUser(long partyId){
        List<UserBasic> userBasics = this.getUserBasicsByPartyId(partyId,null,null);
        String sql = "update userdb.user_basic set state = 0, version = REPLACE(unix_timestamp(current_timestamp(3)),'.','') where  party_id = " + partyId;
        userDao.executeSql(sql);
        if(userBasics != null){
            for(UserBasic userBasic :userBasics){
                CmdUtil.sendImMsg(10000, userBasic.getUid(), 0, GlobalConstant.IMS_REMOVE_STOP, "");
            }
        }
    }

    public void excuteTaskSql(String sql) throws Exception{
        userDao.executeSql(sql);
    }

    public List<RechargeRecord> queryRechargeRecord(RechargeRecord rechargeRecord, PageFilter pageFilter) throws Exception {
        String hql = "from RechargeRecord where 1=1 ";
        HashMap params = new HashMap();
        return rechargeRecordDao.find(hql + rechargeRecordWhereHql(rechargeRecord, params) + " order by rcdId desc ", params, pageFilter.getPage(), pageFilter.getRows());
    }

    public long countRechargeRecord(RechargeRecord rechargeRecord) throws Exception {
        String hql = "select count(*) from RechargeRecord where 1=1 ";
        HashMap params = new HashMap();
        return rechargeRecordDao.count(hql + rechargeRecordWhereHql(rechargeRecord, params), params);
    }



    /**
     * 拼装用户条件
     *
     * @param bean
     * @param params
     * @return
     */
    private String rechargeRecordWhereHql(RechargeRecord bean, Map<String, Object> params) throws Exception {
        String hql = "";
        if (bean != null) {
            if (NumberUtils.isNotNullOrZero(bean.getObj1PartyId())) {
                hql += " and obj1PartyId = :obj1PartyId";
                params.put("obj1PartyId", bean.getObj1PartyId());
            }

            if (StringUtils.isNotBlank(bean.getObj1PartyName())) {
                hql += " and obj1PartyName like :obj1PartyName";
                params.put("obj1PartyName", "%" + URLDecoder.decode(bean.getObj1PartyName(), "UTF-8") + "%");
            }
            if (NumberUtils.isNotNullOrZero(bean.getObj2PartyId())) {
                hql += " and obj2PartyId = :obj2PartyId";
                params.put("obj2PartyId", bean.getObj2PartyId());
            }

            if (StringUtils.isNotBlank(bean.getObj2PartyName())) {
                hql += " and obj2PartyName like :obj2PartyName";
                params.put("obj2PartyName", "%" + URLDecoder.decode(bean.getObj2PartyName(), "UTF-8") + "%");
            }
            if (NumberUtils.isNotNullOrZero(bean.getObj1Uid())) {
                hql += " and obj1Uid = :obj1Uid";
                params.put("obj1Uid", bean.getObj1Uid());
            }
            if (StringUtils.isNotBlank(bean.getObj1Uname())) {
                hql += " and obj1Uname like :obj1Uname";
                params.put("obj1Uname", "%" + URLDecoder.decode(bean.getObj1Uname(), "UTF-8") + "%");
            }
            if (NumberUtils.isNotNullOrZero(bean.getObj1Type())) {
                hql += " and obj1Type = :obj1Type";
                params.put("obj1Type", bean.getObj1Type());
            }
            if (NumberUtils.isNotNullOrZero(bean.getObj2Type())) {
                hql += " and obj2Type = :obj2Type";
                params.put("obj2Type", bean.getObj2Type());
            }
            if (NumberUtils.isNotNullOrZero(bean.getChgType())) {
                hql += " and chgType = :chgType";
                params.put("chgType", bean.getChgType());
            }
            if (bean.getStartDate() != null) {
                hql += " and createTime >= :startDate";
                params.put("startDate", bean.getStartDate());
            }
            if (bean.getEndDate() != null) {
                hql += " and createTime <= :endDate";
                params.put("endDate", bean.getEndDate());
            }
            if (NumberUtils.isNotNullOrZero(bean.getBusiType())) {
                hql += " and busiType = :busiType";
                params.put("busiType", bean.getBusiType());
            }


        }
        return hql;
    }

    @Override
    public void setRechargeRecordRemark(long logId, String remark) throws ViChatException {
        RechargeRecord rechargeRecordFDB = this.getRechargeRecordById(logId);
        if (rechargeRecordFDB != null) {
            rechargeRecordFDB.setRemark(remark);
            rechargeRecordDao.update(rechargeRecordFDB);
        } else {
            String errorMsg = I18NUtil.getMessage("error_recordNotExist", null, Locale.CHINA);
            throw new ViChatException(I18nConstant.error_recordNotExist, errorMsg);
        }
    }

    public RechargeRecord getRechargeRecordById(long rcdId) {
        return rechargeRecordDao.get(RechargeRecord.class, rcdId);
    }

    public List<UserBasicVO> queryUserBasicToRoom(UserBasic bean, PageFilter pf,String userType) throws Exception{
        String hql = "select uid as uid,user_name as userName,terminal as terminal, org_name  as orgName from userdb.user_basic a, userdb.user_org b where a.state in (1,9) and a.org_id = b.org_id ";
        HashMap params = new HashMap();

        if (NumberUtils.isNotNullOrZero(bean.getUid())) {
            hql += " and uid = :uid";
            params.put("uid", bean.getUid());
        }

        if (StringUtils.isNotBlank(bean.getUserName())) {
            hql += " and (user_name like :userName or imei like :userName or terminal like :userName )";
            params.put("userName", "%" + URLDecoder.decode(bean.getUserName(), "UTF-8") + "%");
        }

        if (StringUtils.isNotBlank(bean.getTerminal())) {
            hql += " and terminal = :terminal";
            params.put("terminal", "%" + bean.getTerminal() + "%");
        }
        if (NumberUtils.isNotNullOrZero(bean.getPartyId())) {
            hql += " and a.party_id = :partyId";
            params.put("partyId", bean.getPartyId());
        }
        if (NumberUtils.isNotNullOrZero(bean.getOrgId())) {
            UserOrg orgFDB = this.queryUserOrgByOrgId(bean.getOrgId());
            if (orgFDB.getParentId() != 0) {
                hql += " and a.org_code like :orgCode";
                params.put("orgCode", orgFDB.getOrgCode() + "%");
            }
        }
        if(StringUtils.isNotBlank(userType)){
            hql += " and user_type in ("+ userType +")";
        }

        List<UserBasicVO> users = userDao.findVoBySql(hql, params, UserBasicVO.class, pf.getPage(), pf.getRows());

        return users;
    }

    /**
     * 查询用户数量
     *
     * @param bean
     * @return
     */
    public BigInteger countUserBasicToRoom(UserBasic bean) throws Exception {
        String hql = "select count(*) from userdb.user_basic a, userdb.user_org b where a.state in (1,9) and a.org_id = b.org_id ";
        Map<String, Object> params = new HashMap<String, Object>();
        if (NumberUtils.isNotNullOrZero(bean.getUid())) {
            hql += " and uid = :uid";
            params.put("uid", bean.getUid());
        }

        if (StringUtils.isNotBlank(bean.getUserName())) {
            hql += " and (user_name like :userName or imei like :userName or terminal like :userName )";
            params.put("userName", "%" + URLDecoder.decode(bean.getUserName(), "UTF-8") + "%");
        }

        if (StringUtils.isNotBlank(bean.getTerminal())) {
            hql += " and terminal = :terminal";
            params.put("terminal", "%" + bean.getTerminal() + "%");
        }
        if (NumberUtils.isNotNullOrZero(bean.getPartyId())) {
            hql += " and a.party_id = :partyId";
            params.put("partyId", bean.getPartyId());
        }
        if (NumberUtils.isNotNullOrZero(bean.getOrgId())) {
            UserOrg orgFDB = this.queryUserOrgByOrgId(bean.getOrgId());
            if (orgFDB.getParentId() != 0) {
                hql += " and a.org_code like :orgCode";
                params.put("orgCode", orgFDB.getOrgCode() + "%");
            }
        }
        if(!GlobalConstant.SUPPORT_ADMIN_LOGIN_APP){
            hql += " and user_type in (3,4)";
        }
        return userDao.countBySql(hql, params);
    }

    @Override
    public void updateExpiredDate(UserBasic sessionUser, UserBasic userFDB, Integer monthNumber) throws ViChatException {
        UserPartyCompany company = this.getUserPartyCompanyByPartyId(sessionUser.getPartyId());
        if (company != null) {

            rechargeRecordUserIn(sessionUser, userFDB, company, monthNumber);

            rechargeRecordUserOut(sessionUser, userFDB, company, monthNumber);

            //更新所剩额度
            company.setAuthMonth(company.getAuthMonth() - monthNumber);
            userPartyCompanyDao.update(company);
            RedisHelper.setPartyCompany(company.getPartyId(), JSONObject.toJSONString(company));
        } else {
            String errorMsg = I18NUtil.getMessage("error_agentCompanyNotExist", null, Locale.CHINA);
            throw new ViChatException(I18nConstant.error_agentCompanyNotExist, errorMsg);
        }
    }

    private void rechargeRecordUserIn(UserBasic sessionUser, UserBasic userFDB, UserPartyCompany company, Integer monthNumber) {
        Date oldExpiredDate = userFDB.getExpiredDate();
        Date newExpiredDate = DateUtil.addMonth(userFDB.getExpiredDate(), monthNumber);


        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setObj1PartyId(company.getPartyId());
        rechargeRecord.setObj1PartyName(company.getCompanyName());
        rechargeRecord.setObj1Type(3L);
        rechargeRecord.setObj1Uid(userFDB.getUid());
        rechargeRecord.setObj1Uname(userFDB.getUserName());
        rechargeRecord.setObj2PartyId(company.getPartyId());
        rechargeRecord.setObj2PartyName(company.getCompanyName());
        rechargeRecord.setObj2Type(2L);
        rechargeRecord.setObj2Uid(sessionUser.getUid());
        rechargeRecord.setObj2Uname(sessionUser.getUserName());
        rechargeRecord.setBusiType(1L);
        rechargeRecord.setChgBefore(DateUtil.getFormattedDate(oldExpiredDate));
        rechargeRecord.setChgAfter(DateUtil.getFormattedDate(newExpiredDate));
        rechargeRecord.setChgValue((long) monthNumber);
        rechargeRecord.setChgType(1L);
        rechargeRecord.setCreateTime(new Date());
        rechargeRecordDao.save(rechargeRecord);

        userFDB.setExpiredDate(newExpiredDate);
        userDao.update(userFDB);
        RedisHelper.setUser(userFDB.getUid(), JSONObject.toJSONString(userFDB));
    }

    private void rechargeRecordUserOut(UserBasic sessionUser, UserBasic userFDB, UserPartyCompany company, Integer monthNumber) {
        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setObj2PartyId(company.getPartyId());
        rechargeRecord.setObj2PartyName(company.getCompanyName());
        rechargeRecord.setObj2Type(3L);
        rechargeRecord.setObj2Uid(userFDB.getUid());
        rechargeRecord.setObj2Uname(userFDB.getUserName());
        rechargeRecord.setObj1PartyId(company.getPartyId());
        rechargeRecord.setObj1PartyName(company.getCompanyName());
        rechargeRecord.setObj1Type(2L);
        rechargeRecord.setObj1Uid(sessionUser.getUid());
        rechargeRecord.setObj1Uname(sessionUser.getUserName());
        rechargeRecord.setBusiType(1L);
        rechargeRecord.setChgBefore(String.valueOf(company.getAuthMonth()));
        rechargeRecord.setChgAfter(String.valueOf(company.getAuthMonth() - monthNumber));
        rechargeRecord.setChgValue((long) (0 - monthNumber));
        rechargeRecord.setChgType(2L);
        rechargeRecord.setCreateTime(new Date());

        rechargeRecordDao.save(rechargeRecord);
    }

    public List<UserBasic> queryExpiredUser(){
        String hql = "select * from userdb.user_basic where state = 1 and TIMESTAMPDIFF(day,expired_date,NOW()) >= 1 and TIMESTAMPDIFF(day,expired_date,NOW()) <= 2";
        HashMap params = new HashMap();
        return userDao.findEntityBySql(hql,params,UserBasic.class);
    }

    public List<UserBasic> queryUserByFuncDesc(String[] funcDesc, long pOrgId) {
        String hql = "select distinct a.* from userdb.user_basic a,userdb.user_sec_role_rel b ,userdb.sec_role c , userdb.sec_role_function d, userdb.sec_function e " +
                " where a.uid = b.uid and b.roid = c.roid and c.roid = d.roid and d.fid = e.fid" +
                " and e.func_desc in (" + Strings.join(Arrays.asList(funcDesc), ",") + ") and c.p_org_id in (0," + pOrgId + ") and a.state = 1 and a.user_type in (2,3)";
        HashMap params = new HashMap();
        return userDao.findEntityBySql(hql, params, UserBasic.class);
    }

    public List<SysBusiRecord> querySysBusiRecord(SysBusiRecord queryBean, PageFilter pageFilter) {
        String hql = "from SysBusiRecord a where 1=1 ";
        HashMap params = new HashMap();
        return sysBusiRecordDao.find(hql + sysBusiRecordWhereHql(queryBean, params), params, pageFilter.getPage(), pageFilter.getRows());
    }

    public long countSysBusiRecord(SysBusiRecord queryBean) {
        String hql = "select count(*) from SysBusiRecord a where 1=1";
        HashMap params = new HashMap();
        return sysBusiRecordDao.count(hql + sysBusiRecordWhereHql(queryBean, params), params);
    }

    private String sysBusiRecordWhereHql(SysBusiRecord queryBean, HashMap params) {
        String hql = "";
        if (StringUtils.isNotBlank(queryBean.getOpedInfo())) {
            hql += " and opedInfo like :opedInfo";
            params.put("opedInfo", "%" + queryBean.getOpedInfo() + "%");
        }
        if (StringUtils.isNotBlank(queryBean.getOpedType())) {
            hql += " and opedType like :opedType";
            params.put("opedType", "%" + queryBean.getOpedType() + "%");
        }
        if (StringUtils.isNotBlank(queryBean.getUserName())) {
            hql += " and userName like :userName";
            params.put("userName", "%" + queryBean.getUserName() + "%");
        }
        if (StringUtils.isNotBlank(queryBean.getRemark())) {
            hql += " and remark like :remark";
            params.put("remark", "%" + queryBean.getRemark() + "%");
        }
        if (NumberUtils.isNullOrZero(queryBean.getOrgId()) && StringUtils.isNotBlank(RedisHelper.getOrgCode(queryBean.getOrgId()))) {
            hql += " and orgCode like :orgCode";
            params.put("orgCode", RedisHelper.getOrgCode(queryBean.getOrgId()) + "%");
        }
        if (NumberUtils.isNullOrZero(queryBean.getPartyId())) {
            hql += " and partyId = :partyId";
            params.put("partyId", queryBean.getPartyId());
        }
        if (queryBean.getStartTime() != null) {
            hql += " and createTime >= :startTime";
            params.put("startTime", queryBean.getStartTime());
        }
        if (queryBean.getEndTime() != null) {
            hql += " and createTime <= :endTime";
            params.put("endTime", queryBean.getEndTime());
        }
        return hql;
    }

    public List<UserBasic> getUserBasicsByRole(long roleId,Long orgId ,String orgCode){
        String hql = "select b from UserSecRoleRel a ,UserBasic b  where a.state = 1 and b.state = 1 and a.roleId = :roleId and a.uid = b.uid";
        HashMap params = new HashMap();
        params.put("roleId",roleId);
        if(NumberUtils.isNotNullOrZero(orgId)){
            hql += " and b.orgId = :orgId";
            params.put("orgId",orgId);
        }
        else if(StringUtils.isNotBlank(orgCode)){
            hql += " and b.orgCode like :orgCode";
            params.put("orgCode",orgCode+"%");
        }
        return userDao.find(hql,params);
    }
}